/******************************************************************************
* project: automatic_alarm_free_rtos_based
* chip: STM32F407VG
* compiler: arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.6.2
* 	20110921 (release) [ARM/embedded-4_6-branch revision 182083]
*
* prefix: (none)
*
* available global functions:
* 	spi_init(void)
* 	spi_write(uint32_t regdata)
* 	spi_read(uint32_t *regdata)
*
*
* available local functions:
*
*
* available interrupt handlers:
******************************************************************************/

/*
+=============================================================================+
| includes
+=============================================================================+
*/
#include "stm_spi.h"
#include "gpio.h"
#include "config.h"
#include "stm32f4xx.h"


/*------------------------------------------------------------------------*//**
* global functions
*
*//*-------------------------------------------------------------------------*/

/*------------------------------------------------------------------------*//**
* \brief Configures and initialize ACC SPI.
* \details
*
* \param [in] void
*//*-------------------------------------------------------------------------*/
void acc_spi_init(void)
{
   RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;    //turn on the clock

   gpio_pin_cfg(ACC_GPIO, ACC_MISO_pin, GPIO_AF5_PP_100MHz);
   gpio_pin_cfg(ACC_GPIO, ACC_MOSI_pin, GPIO_AF5_PP_100MHz);
   gpio_pin_cfg(ACC_GPIO, ACC_SCK_pin, GPIO_AF5_PP_100MHz);         	//MISO
   gpio_pin_cfg(ACC_CS_GPIO, ACC_CS_pin, GPIO_OUT_PP_100MHz);

   ACC_CS_bb = 1;

   SPI1->CR1 |= SPI_CR1_BR_0 | SPI_CR1_BR_1;

   //configure SPI
   SPI1->CR1 |= SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_DFF \
		   | SPI_CR1_CPOL |SPI_CR1_CPHA | SPI_CR1_SPE;

}

/*------------------------------------------------------------------------*//**
* \brief Read/wrie byte from/to SPI.
* \details
*
* \param [in] void
*//*-------------------------------------------------------------------------*/
uint16_t acc_spi_transfer(SPI_TypeDef* mySPI, uint16_t data)
{
	ACC_CS_bb = 0;

	while (!(mySPI->SR & SPI_SR_TXE));	//Wait if TXE cleared, Tx FIFO is full.
	mySPI->DR = data;
	while (!(mySPI->SR & SPI_SR_RXNE));	//Wait if RNE cleared, Rx FIFO is empty.
	data = mySPI->DR;

	ACC_CS_bb = 1;

	return data;
}

/*------------------------------------------------------------------------*//**
* \brief Configures and initialize SDcard SPI.
* \details
*
* \param [in] void
*//*-------------------------------------------------------------------------*/
void sdcard_spi_init(void)
{
   RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;    //turn on the clock

   gpio_pin_cfg(SD_GPIO, SD_MISO_pin, GPIO_AF5_PP_100MHz);
   gpio_pin_cfg(SD_GPIO, SD_MOSI_pin, GPIO_AF5_PP_100MHz);
   gpio_pin_cfg(SD_GPIO, SD_SCK_pin,  GPIO_AF5_PP_100MHz);
   gpio_pin_cfg(SD_GPIO, SD_CS_pin,   GPIO_OUT_PP_100MHz);

   SD_CS_bb = 1;

   SPI2->CR1 |= SPI_CR1_BR_0 | SPI_CR1_BR_1;

   //configure the SPI
   SPI2->CR1 |= SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI \
		   | SPI_CR1_CPOL |SPI_CR1_CPHA | SPI_CR1_SPE;

}

/*------------------------------------------------------------------------*//**
* \brief Read/wrie byte from/to SPI.
* \details
*
* \param [in] void
*//*-------------------------------------------------------------------------*/
uint8_t sdcard_spi_transfer(SPI_TypeDef* mySPI, uint8_t data)
{
	while (!(mySPI->SR & SPI_SR_TXE));	//Wait if TXE cleared, Tx FIFO is full.
	mySPI->DR = data;
	while (!(mySPI->SR & SPI_SR_RXNE));	//Wait if RNE cleared, Rx FIFO is empty.
	data = mySPI->DR;

	return data;
}

